﻿using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections.Generic;
using System.Drawing;
using System.ComponentModel;

namespace WindowAPI
{
    /// <summary> 
    /// 这个类可以让你得到一个在运行中程序的所有键盘事件 
    /// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息 
    /// </summary> 
    /// <remarks> 
    /// 修改:lihx 
    /// 修改时间:04.11.8 
    /// </remarks> 
    public class MouseHook
    {

        public const int WH_MOUSE_LL = 14;
        private const int WM_MOUSEMOVE = 0x200;
        private const int WM_RBUTTONUP = 0x205;
        private const int WM_RBUTTONDOWN = 0x204;
        private const int WM_LBUTTONDOWN = 0x201;
        private const int WM_LBUTTONUP = 0x202;

        public static int nowHockPart = 0;

        private int newcount = 0;
        private static object EVENT_MOUSEMOVE = new object();
        public event MouseEventHandler MouseMove
        {
            add
            {
                Events.AddHandler(EVENT_MOUSEMOVE, value);
            }
            remove
            {
                Events.RemoveHandler(EVENT_MOUSEMOVE, value);
            }
        }
        private static object EVENT_MOUSEDOWN = new object();
        public event MouseEventHandler MouseDown
        {
            add
            {
                Events.AddHandler(EVENT_MOUSEDOWN, value);
            }
            remove
            {
                Events.RemoveHandler(EVENT_MOUSEDOWN, value);
            }
        }
        private static object EVENT_MOUSEUP = new object();
        public event MouseEventHandler MouseUp
        {
            add
            {
                Events.AddHandler(EVENT_MOUSEUP, value);
            }
            remove
            {
                Events.RemoveHandler(EVENT_MOUSEUP, value);
            }
        }

        protected EventHandlerList Events;

        static int hMouseHook = 0; //键盘钩子句柄

        private HookProc MouseHookProcedure; //声明键盘钩子事件类型.


        public struct MouseStruct
        {
            public Point p;
            public IntPtr HWnd;
            public uint wHitTestCode;
            public int dwExtraInfo;
        }


        //装置钩子的函数 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        //卸下钩子的函数 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //下一个钩挂的函数 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

        [DllImport("user32")]
        public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);

        [DllImport("user32")]
        public static extern int GetKeyboardState(byte[] pbKeyState);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

        /// <summary> 
        /// 墨认的构造函数构造当前类的实例并自动的运行起来. 
        /// </summary> 
        public MouseHook()
        {
            this.Events = new EventHandlerList();
            //   Start();
        }

        //析构函数. 
        ~MouseHook()
        {
            Stop();
        }

        public void Start()
        {
            //安装鼠标钩子 
            if (hMouseHook == 0)
            {
                MouseHookProcedure = new HookProc(MouseHookProc);
                //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
                Process curProcess = Process.GetCurrentProcess();
                ProcessModule curModule = curProcess.MainModule;

                hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, GetModuleHandle(curModule.ModuleName), 0);

                if (hMouseHook == 0)
                {
                    Stop();
                    throw new Exception("SetWindowsHookEx ist failed.");
                }
            }
        }

        public void Stop()
        {
            bool retMouse = true;

            if (hMouseHook != 0)
            {
                retMouse = UnhookWindowsHookEx(hMouseHook);
                hMouseHook = 0;
            }
            //如果卸下钩子失败 
            if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed.");
        }
        private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            if (wParam == WM_LBUTTONDOWN)
            {
                int x = Control.MousePosition.X;
                int y = Control.MousePosition.Y;

                System.Drawing.Bitmap img = WindowAPI.ApiHelper.GetScreenMap();
                System.Drawing.Color color = img.GetPixel(x, y);
                //记录的怪物记录点
                if (nowHockPart == -2)
                {
                    WindowAPI.GuaiwuExistPoint point = new GuaiwuExistPoint();
                    point.R = color.R;
                    point.G = color.G;
                    point.B = color.B;
                    point.X = x;
                    point.Y = y;
                    point.Insert();
                }
                else//血量记录点
                {
                    WindowAPI.NeedAddBooldPoint pick = new NeedAddBooldPoint();
                    pick.Part = nowHockPart;
                    pick.R = color.R;
                    pick.G = color.G;
                    pick.B = color.B;
                    pick.X = x;
                    pick.Y = y;
                    pick.Insert();
                }


                img = null;

                newcount++;

                if (newcount == 4)
                {
                    this.Stop();
                }

                //    ("采集点：(" + x + "," + y + ")；颜色：" + color.R.ToString() + "-" + color.G.ToString() + "-" + color.B.ToString()).Debug();

            }
            return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
        }
    }
}
